/// 评分组件
/// 参照Element UI的Rate控件实现

import 'package:flutter/material.dart';
import '../../core/elegance_theme.dart';
import '../../core/elegance_base.dart';

/// 评分组件
class ERate extends StatefulWidget {
  /// 创建评分组件
  const ERate({
    super.key,
    this.value = 0,
    this.max = 5,
    this.disabled = false,
    this.allowHalf = false,
    this.lowThreshold = 2,
    this.highThreshold = 4,
    this.colors = const ['#F7BA2A', '#F7BA2A', '#F7BA2A'],
    this.voidColor = '#C6D1DE',
    this.disabledVoidColor = '#EFF2F7',
    this.iconClasses = const ['el-icon-star-on', 'el-icon-star-on', 'el-icon-star-on'],
    this.voidIconClass = 'el-icon-star-off',
    this.disabledVoidIconClass = 'el-icon-star-on',
    this.showText = false,
    this.showScore = false,
    this.textColor = '#1F2D3D',
    this.texts = const ['极差', '失望', '一般', '满意', '惊喜'],
    this.scoreTemplate = '{value}',
    this.onChange,
  });

  /// 绑定值
  final double value;

  /// 最大分值
  final int max;

  /// 是否为只读
  final bool disabled;

  /// 是否允许半选
  final bool allowHalf;

  /// 低分和中等分数的界限值，值本身被划分在低分中
  final int lowThreshold;

  /// 高分和中等分数的界限值，值本身被划分在高分中
  final int highThreshold;

  /// icon的颜色。若传入数组，共有3个元素，为3个分段所对应的颜色；若传入对象，可自定义分段
  final dynamic colors;

  /// 未选中icon的颜色
  final String voidColor;

  /// 只读时未选中icon的颜色
  final String disabledVoidColor;

  /// icon的类名。若传入数组，共有3个元素，为3个分段所对应的类名；若传入对象，可自定义分段
  final dynamic iconClasses;

  /// 未选中icon的类名
  final String voidIconClass;

  /// 只读时未选中icon的类名
  final String disabledVoidIconClass;

  /// 是否显示辅助文字
  final bool showText;

  /// 是否显示当前分数，showScore和showText不能同时为真
  final bool showScore;

  /// 辅助文字的颜色
  final String textColor;

  /// 辅助文字数组
  final List<String> texts;

  /// 分数显示模板
  final String scoreTemplate;

  /// 分值改变时触发
  final ValueChanged<double>? onChange;

  @override
  State<ERate> createState() => _ERateState();
}

class _ERateState extends State<ERate> with ThemedMixin {
  double _value = 0;

  @override
  void initState() {
    super.initState();
    _value = widget.value;
  }

  @override
  void didUpdateWidget(covariant ERate oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.value != widget.value) {
      _value = widget.value;
    }
  }

  /// 获取指定分数对应的颜色
  Color _getColor(double score) {
    if (widget.colors is List<String>) {
      List<String> colorList = widget.colors as List<String>;
      if (score <= widget.lowThreshold) {
        return _parseColor(colorList[0]);
      } else if (score <= widget.highThreshold) {
        return _parseColor(colorList[1]);
      } else {
        return _parseColor(colorList[2]);
      }
    } else if (widget.colors is Map<String, String>) {
      Map<String, String> colorMap = widget.colors as Map<String, String>;
      // 按分数从高到低查找对应的颜色
      List<double> thresholds = colorMap.keys.map((key) => double.parse(key)).toList();
      thresholds.sort((a, b) => b.compareTo(a));
      
      for (double threshold in thresholds) {
        if (score >= threshold) {
          return _parseColor(colorMap[threshold.toString()]!);
        }
      }
      return _parseColor(colorMap.values.last);
    }
    return _parseColor('#F7BA2A');
  }

  /// 解析颜色字符串为Color对象
  Color _parseColor(String colorStr) {
    try {
      if (colorStr.startsWith('#')) {
        colorStr = colorStr.substring(1);
        if (colorStr.length == 6) {
          return Color(int.parse('0xff$colorStr'));
        } else if (colorStr.length == 8) {
          return Color(int.parse(colorStr, radix: 16));
        }
      }
    } catch (e) {
      // 解析失败时返回默认颜色
    }
    return Colors.orangeAccent;
  }

  /// 处理点击评分
  void _handleClick(int index, bool isHalf) {
    if (widget.disabled) return;

    double newValue = index + 1.0;
    if (widget.allowHalf && isHalf) {
      newValue -= 0.5;
    }

    setState(() {
      _value = newValue;
    });
    widget.onChange?.call(newValue);
  }

  /// 处理鼠标悬停（触摸滑动）评分预览
  void _handleHover(int index, bool isHalf) {
    if (widget.disabled) return;
    
    // 在实际应用中，这里可以实现预览效果
    // 但Flutter的GestureDetector没有直接的悬停事件
    // 可以通过Pan手势来模拟滑动评分
  }

  /// 获取分数对应的文本
  String _getScoreText() {
    if (widget.showText) {
      int index = (_value - 1).clamp(0, widget.texts.length - 1).toInt();
      return widget.texts[index];
    } else if (widget.showScore) {
      return widget.scoreTemplate.replaceAll('{value}', _value.toString());
    }
    return '';
  }

  /// 构建星星图标
  Widget _buildStar(int index) {
    final currentScore = index + 1.0;
    final isActive = currentScore <= _value;
    final isHalfActive = widget.allowHalf && currentScore - 0.5 <= _value && currentScore > _value;
    
    Color color = _getColor(_value);
    Color voidColor = widget.disabled ? _parseColor(widget.disabledVoidColor) : _parseColor(widget.voidColor);
    
    return GestureDetector(
      onTapDown: (details) {
        if (!widget.disabled) {
          final box = context.findRenderObject() as RenderBox;
          final position = box.globalToLocal(details.globalPosition);
          final isHalf = widget.allowHalf && position.dx < box.size.width / 2;
          _handleClick(index, isHalf);
        }
      },
      child: Container(
        decoration: BoxDecoration(
          color: Colors.transparent,
        ),
        padding: const EdgeInsets.all(2),
        child: Stack(
          children: [
            // 空星
            Icon(
              Icons.star_border, // 使用Flutter内置图标代替Element UI的图标类
              size: 20,
              color: voidColor,
            ),
            // 实心星
            if (isActive) ...[
              Icon(
                Icons.star, // 使用Flutter内置图标代替Element UI的图标类
                size: 20,
                color: color,
              ),
            ],
            // 半星
            if (isHalfActive && widget.allowHalf) ...[
              ClipRect(
                clipper: HalfStarClipper(),
                child: Icon(
                  Icons.star, // 使用Flutter内置图标代替Element UI的图标类
                  size: 20,
                  color: color,
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    // 根据主题调整样式
    final textStyle = TextStyle(
      color: _parseColor(widget.textColor),
      fontSize: 14,
    );

    return Container(
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 星星图标组
          Row(
            children: List.generate(widget.max, (index) => _buildStar(index)),
          ),
          // 辅助文字
          if (widget.showText || widget.showScore) ...[
            const SizedBox(width: 8),
            Text(
              _getScoreText(),
              style: textStyle,
            ),
          ],
        ],
      ),
    );
  }
}

/// 用于裁剪半星的Clipper
class HalfStarClipper extends CustomClipper<Rect> {
  @override
  Rect getClip(Size size) {
    return Rect.fromLTRB(0, 0, size.width / 2, size.height);
  }

  @override
  bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {
    return false;
  }
}